﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using AutoMapper;
using Com.DataAccess.FinancingCredit;
using Com.Enums.Core;
using Com.Enums.Market.Order;
using Com.Enums.Shop.Credit;
using Com.Enums.Store;
using Com.Framework.Extension;
using Com.Model.FinancingCredit;
using Com.Service.DTO.Shop.Credit;
using Com.ThirdParty.Common;
using Com.DataAccess.FinancingCredit.Repository;
using Com.Domain.Core.EFRepository;
using Com.Enums.Shop;
using Com.Framework.Tenant;
using Com.Framework.Base;
using Com.Service.Core.EFService;

namespace Com.Service.Admin
{
    public interface IFinancingCreditService : IEFService
    {
        IList<MemberCreditDTO> ImportCustomerDataFromExcel(Stream stream);

        MemberCreditDTO SendMemberCredit(MemberCreditDTO membercredit, MemberCreditDTO type = null);

        bool RemoveMemberCredit(MemberCreditDTO membercredit);
    }
    public class FinancingCreditService : EFServiceBase, IFinancingCreditService
    {
        protected EFUnitOfWorkContextBase FinancingCreditContext { get; private set; }
        #region 额度
        private MemberCreditRepository _memberCreditRepository;
        private readonly MemberCreditConditionRepository _memberCreditConditionRepository;
        private readonly MemberCreditChangeLogRepository _memberCreditChangeLogRepository;
        #endregion

        #region 消费记录
        private readonly CreditUsageDetailRepository _creditUsageDetailRepository;
        private readonly CreditUsageConditionRepository _creditUsageConditionRepository;
        private readonly CreditUsageContractRepository _creditUsageContractRepository;
        #endregion

        #region 还款
        private readonly RepaymentRemindRepository _repaymentRemindRepository;
        private readonly RepaymentInterestDetailRepository _repaymentInterestDetailRepository;
        #endregion

        public FinancingCreditService(Tenant tenant)
            : base(tenant)
        {
            FinancingCreditContext = new ComFinancingCreditUnitOfWorkContext(tenant);
            _memberCreditConditionRepository = new MemberCreditConditionRepository(FinancingCreditContext);
            _memberCreditChangeLogRepository = new MemberCreditChangeLogRepository(FinancingCreditContext);
            _creditUsageDetailRepository = new CreditUsageDetailRepository(FinancingCreditContext);
            _creditUsageConditionRepository = new CreditUsageConditionRepository(FinancingCreditContext);
            _memberCreditRepository = new MemberCreditRepository(FinancingCreditContext);
            _repaymentRemindRepository = new RepaymentRemindRepository(FinancingCreditContext);
            _creditUsageContractRepository = new CreditUsageContractRepository(FinancingCreditContext);
            _repaymentInterestDetailRepository = new RepaymentInterestDetailRepository(FinancingCreditContext);
        }


        public IList<MemberCreditDTO> ImportCustomerDataFromExcel(Stream stream)
        {
            var dataSet = new NPOIExcelReader(stream).GetDataset();
            var credits = new List<MemberCreditDTO>();
            var usages = new List<CreditUsageDetailDTO>();
            var reminds = new List<RepaymentRemindDTO>();
            var usageCondition = new List<CreditUsageConditionDTO>();
            foreach (System.Data.DataTable dt in dataSet.Tables)
            {
                switch (dt.TableName)
                {
                    case "额度数据填写模板":
                        MemberCreditDTO credit = null;
                        foreach (System.Data.DataRow dr in dt.Rows)
                        { //所有列
                            credit = new MemberCreditDTO
                            {
                                SyncStatus = SyncStatus.SyncSuccess,
                                Remark = "Excel导入数据"
                            };
                            foreach (System.Data.DataColumn dc in dr.Table.Columns)
                            {
                                switch (dc.ColumnName.Trim())
                                {
                                    case "申请客户的租户代码":
                                        credit.CustomerUserName = dr[dc].ToString();
                                        break;
                                    case "申请客户名称":
                                        credit.CustomerDisplayName = dr[dc].ToString();
                                        break;
                                    case "授信额度":
                                        credit.CreditLimit = dr[dc].IsNullOrEmpty() ? 0 : dr[dc].ObjToDecimal();
                                        break;
                                    case "授信开始时间":
                                        credit.CreditStartDate = dr[dc].IsNullOrEmpty() ? null : dr[dc].ObjToDateNull();
                                        break;
                                    case "授信结束时间":
                                        credit.CreditEndDate = dr[dc].IsNullOrEmpty() ? null : dr[dc].ObjToDateNull();
                                        break;
                                    case "批复利率":
                                        credit.CreditAnnualRate = dr[dc].IsNullOrEmpty() ? 0 : Convert.ToDouble(dr[dc]);
                                        break;
                                    case "批复罚息利率":
                                        credit.PenaltyRate = dr[dc].IsNullOrEmpty() ? 0 : Convert.ToDouble(dr[dc]);
                                        break;
                                    case "额度状态":
                                        switch (dr[dc].ToString().Trim())
                                        {
                                            case "额度可用":
                                                credit.Status = MemberCreditStatus.Through;
                                                break;
                                            case "使用中":
                                                credit.Status = MemberCreditStatus.Available;
                                                break;
                                            case "冻结":
                                                credit.Status = MemberCreditStatus.Freeze;
                                                credit.IsBlocked = true;
                                                break;
                                        }
                                        break;
                                    case "还款类型":
                                        switch (dr[dc].ToString().Trim())
                                        {
                                            case "等额本息":
                                                credit.RepaymentType = RepaymentType.EqualPrincipal;
                                                break;
                                            case "等额本金":
                                                credit.RepaymentType = RepaymentType.EqualPrincipalAndInterest;
                                                break;
                                            case "一次还本付息":
                                                credit.RepaymentType = RepaymentType.OneOff;
                                                break;
                                            case "自主还款":
                                                credit.RepaymentType = RepaymentType.Discretionary;
                                                break;
                                            case "先息后本":
                                                credit.RepaymentType = RepaymentType.InterestFirst;
                                                break;
                                            case "等本等息":
                                                credit.RepaymentType = RepaymentType.Waitingfortherate;
                                                break;
                                            case "一次付息分期还本":
                                                credit.RepaymentType = RepaymentType.PoundagePrincipal;
                                                break;
                                        }
                                        break;
                                    case "额度标签":
                                        switch (dr[dc].ToString().Trim())
                                        {
                                            case "店铺赊销":
                                                credit.CreditLimitTally = Convert.ToInt32(CreditLimitTally.StoreCredit);
                                                credit.OrderType = FinancingOrderType.BuyOnCreditProvider;
                                                credit.CreditLimitType = CreditType.BuyOnCreditProvider;
                                                break;
                                            case "供应链分期":
                                                credit.CreditLimitTally = Convert.ToInt32(CreditLimitTally.SupplyChainFinance);
                                                credit.OrderType = FinancingOrderType.SupplyChainProvider;
                                                credit.CreditLimitType = CreditType.SupplyChainProvider;
                                                break;
                                            case "融资租赁":
                                                credit.CreditLimitTally = Convert.ToInt32(CreditLimitTally.FinanceLease);
                                                credit.OrderType = FinancingOrderType.Provider;
                                                credit.CreditLimitType = CreditType.Provider;
                                                break;
                                            case "商业保理":
                                                credit.CreditLimitTally = Convert.ToInt32(CreditLimitTally.CommercialFactoring);
                                                credit.OrderType = FinancingOrderType.Provider;
                                                credit.CreditLimitType = CreditType.Provider;
                                                break;
                                            case "银行":
                                                credit.CreditLimitTally = Convert.ToInt32(CreditLimitTally.Bank);
                                                credit.OrderType = FinancingOrderType.Provider;
                                                credit.CreditLimitType = CreditType.Provider;
                                                break;
                                            case "小额贷款":
                                                credit.CreditLimitTally = Convert.ToInt32(CreditLimitTally.SmallLoan);
                                                credit.OrderType = FinancingOrderType.Provider;
                                                credit.CreditLimitType = CreditType.Provider;
                                                break;
                                        }
                                        break;
                                    case "额度审批状态":
                                        switch (dr[dc].ToString().Trim())
                                        {
                                            case "未提交":
                                                credit.WorkFlowStatus = WorkFlowStatus.Draft;
                                                credit.FlowStatus = WorkFlowStatus.Draft;
                                                break;
                                            case "审批中":
                                                credit.WorkFlowStatus = WorkFlowStatus.AuditPending;
                                                credit.FlowStatus = WorkFlowStatus.Draft;
                                                break;
                                            case "审批通过":
                                                credit.WorkFlowStatus = WorkFlowStatus.Approved;
                                                credit.FlowStatus = WorkFlowStatus.Approved;
                                                break;
                                            case "审批不通过":
                                                credit.WorkFlowStatus = WorkFlowStatus.Disagree;
                                                credit.FlowStatus = WorkFlowStatus.Disagree;
                                                break;
                                        }
                                        break;
                                    case "放款条件":
                                        usageCondition.Add(new CreditUsageConditionDTO()
                                        {
                                            Name = dr[dc].ToString().Trim(),
                                            Description = "此条件为Excel导入",
                                            Status = ReleaseStatus.Approved
                                        });
                                        credit.MemberCreditConditions = new List<MemberCreditConditionDTO>()
                                        {
                                            new MemberCreditConditionDTO()
                                            {
                                                Name = dr[dc].ToString().Trim(),
                                                Description = "此条件为Excel导入",
                                            }
                                        };
                                        break;
                                }
                            }
                            credits.Add(credit);
                        }
                        break;
                    case "消费记录数据模板":
                        CreditUsageDetailDTO creditusage = null;
                        foreach (System.Data.DataRow dr in dt.Rows)
                        {
                            creditusage = new CreditUsageDetailDTO();
                            var seed = StoredProcedureHelper.GetSeedByType(SeedType.CreditUsage);
                            if (seed != null)
                            {
                                creditusage.Id = seed.SeedValue;
                            }
                            creditusage.Status = CreditUsageStatus.Completed;
                            creditusage.RepaymentPlanStatus = WorkFlowStatus.Approved;
                            creditusage.ConditionStatus = WorkFlowStatus.Approved;
                            creditusage.SyncStatus = SyncStatus.SyncSuccess;
                            creditusage.ConditionSyncStatus = SyncStatus.SyncSuccess;
                            creditusage.RepaymentPlanSyncStatus = SyncStatus.SyncSuccess;
                            creditusage.GuaranteeSyncStatus = SyncStatus.SyncSuccess;
                            creditusage.CreditUsageConditions = usageCondition;
                            foreach (System.Data.DataColumn dc in dr.Table.Columns)
                            {
                                switch (dc.ColumnName.Trim())
                                {
                                    case "消费记录ID（随便填）":
                                        creditusage.CreditUsageDetailId = dr[dc].ToString();
                                        break;
                                    case "客户租户代码":
                                        creditusage.CustomerUserName = dr[dc].ToString();
                                        break;
                                    case "本次消费额度":
                                        creditusage.ConsumptionMoney = dr[dc].IsNullOrEmpty() ? 0 : dr[dc].ObjToDecimal();
                                        break;
                                    case "消费日期":
                                        creditusage.ConsumptionDate = dr[dc].IsNullOrEmpty() ? null : dr[dc].ObjToDateNull();
                                        break;
                                    case "商城订单号（没有就不写）":
                                        creditusage.OrderId = dr[dc].ToString();
                                        break;
                                    case "还款计划年利率":
                                        creditusage.AnnualRate = dr[dc].IsNullOrEmpty() ? 0 : Convert.ToDouble(dr[dc]);
                                        break;
                                    case "还款类型":
                                        switch (dr[dc].ToString().Trim())
                                        {
                                            case "等额本息":
                                                creditusage.RepaymentType = RepaymentType.EqualPrincipal;
                                                break;
                                            case "等额本金":
                                                creditusage.RepaymentType = RepaymentType.EqualPrincipalAndInterest;
                                                break;
                                            case "一次还本付息":
                                                creditusage.RepaymentType = RepaymentType.OneOff;
                                                break;
                                            case "自主还款":
                                                creditusage.RepaymentType = RepaymentType.Discretionary;
                                                break;
                                            case "先息后本":
                                                creditusage.RepaymentType = RepaymentType.InterestFirst;
                                                break;
                                            case "等本等息":
                                                creditusage.RepaymentType = RepaymentType.Waitingfortherate;
                                                break;
                                            case "一次付息分期还本":
                                                creditusage.RepaymentType = RepaymentType.PoundagePrincipal;
                                                break;
                                        }
                                        break;
                                    case "还款状态":
                                        switch (dr[dc].ToString().Trim())
                                        {
                                            case "还款中":
                                                creditusage.RepaymentStatus = RepaymentStatus.InRepayment;
                                                break;
                                            case "已还完":
                                                creditusage.RepaymentStatus = RepaymentStatus.RepaymentComplete;
                                                break;
                                        }
                                        break;
                                    case "需还总金额":
                                        creditusage.ArrearsAmount = dr[dc].IsNullOrEmpty() ? 0 : dr[dc].ObjToDecimal();
                                        break;
                                    case "已还金额":
                                        creditusage.ReceivedRepayment = dr[dc].IsNullOrEmpty() ? 0 : dr[dc].ObjToDecimal();
                                        break;
                                    case "保证金":
                                        creditusage.CashDeposit = dr[dc].IsNullOrEmpty() ? 0 : Convert.ToDouble(dr[dc]);
                                        break;
                                    case "首付款":
                                        creditusage.DownPayment = dr[dc].IsNullOrEmpty() ? 0 : Convert.ToDouble(dr[dc]);
                                        break;
                                    case "是否循环":
                                        creditusage.IsCycle = dr[dc].ToString().Equals("是");
                                        break;
                                    case "还款计划开始日期":
                                        creditusage.StartRepaymentDate = dr[dc].IsNullOrEmpty() ? null : dr[dc].ObjToDateNull();
                                        break;
                                    case "还款计划结束日期":
                                        creditusage.EndRepaymentDate = dr[dc].IsNullOrEmpty() ? null : dr[dc].ObjToDateNull();
                                        break;
                                }
                            }
                            usages.Add(creditusage);
                        }
                        break;
                    case "还款计划数据模板":
                        RepaymentRemindDTO repayment = null;
                        foreach (System.Data.DataRow dr in dt.Rows)
                        {
                            repayment = new RepaymentRemindDTO
                            {
                                RepaymentInterestDetail = new RepaymentInterestDetailDTO(),
                                RemindDate = DateTime.UtcNow
                            };
                            repayment.WorkFlowStatus = WorkFlowStatus.Approved;
                            repayment.SyncStatus = SyncStatus.SyncSuccess;
                            foreach (System.Data.DataColumn dc in dr.Table.Columns)
                            {
                                switch (dc.ColumnName.Trim())
                                {
                                    case "消费记录ID（必须和消费记录对应）":
                                        repayment.WithdrawalOrder = dr[dc].ToString();
                                        break;
                                    case "客户租户代码":
                                        repayment.CustomerUserName = dr[dc].ToString();
                                        break;
                                    case "客户名称":
                                        repayment.CustomerDisplayName = dr[dc].ToString();
                                        break;
                                    case "本期需还款":
                                        repayment.MonthlyRepaymentAmount = dr[dc].IsNullOrEmpty() ? 0 : dr[dc].ObjToDecimal();
                                        break;
                                    case "罚金":
                                        repayment.PenaltyAmount = dr[dc].IsNullOrEmpty() ? 0 : dr[dc].ObjToDecimal();
                                        break;
                                    case "还款日期":
                                        repayment.RepaymentDate = dr[dc].IsNullOrEmpty() ? DateTime.Now : dr[dc].ObjToDate();
                                        break;
                                    case "已还款":
                                        repayment.ReceivedRepayment = dr[dc].IsNullOrEmpty() ? 0 : dr[dc].ObjToDecimal();
                                        break;
                                    case "本金":
                                        repayment.RepaymentInterestDetail.Principal = dr[dc].IsNullOrEmpty() ? 0 : Convert.ToDouble(dr[dc]);
                                        break;
                                    case "利息":
                                        repayment.RepaymentInterestDetail.Interest = dr[dc].IsNullOrEmpty() ? 0 : Convert.ToDouble(dr[dc]);
                                        break;
                                    case "还款状态":
                                        switch (dr[dc].ToString().Trim())
                                        {
                                            case "还款待审核":
                                                repayment.MonthlyRepaymentStatus = RepaymentStatus.AwaitConfirmed;
                                                break;
                                            case "还款中":
                                                repayment.MonthlyRepaymentStatus = RepaymentStatus.InRepayment;
                                                break;
                                            case "已还完":
                                                repayment.MonthlyRepaymentStatus = RepaymentStatus.RepaymentComplete;
                                                break;
                                        }
                                        break;
                                }
                            }
                            reminds.Add(repayment);
                        }
                        break;
                }
            }

            //if (reminds.Any() && !credits.Any())
            //{
            //    var usernames = reminds.Select(m => m.CustomerUserName).ToList().Distinct();
            //    var memberCredit = _memberCreditRepository.GetMemberCreditDetailListByFilter(m => usernames.Contains(m.CustomerUserName));
            //    foreach (var item in memberCredit)
            //    {
            //        foreach (var detail in item.MemberCreditDetails)
            //        {
            //            detail.RepaymentReminds = Mapper.Map<List<RepaymentRemind>>(reminds.Where(m => m.WithdrawalOrder == detail.Id));
            //        }
            //    }
            //    if (_memberCreditRepository.Add(memberCredit) > 0)
            //    {
            //        return Mapper.Map<List<MemberCreditDTO>>(memberCredit);
            //    }
            //    return new List<MemberCreditDTO>();
            //}

            //if (usages.Any())
            //{
            //    if (credits.Any())
            //    {
            List<MemberCredit> dtos = new List<MemberCredit>();
            foreach (var item in credits)
            {
                if (_memberCreditRepository.FindByFilter(n => n.CustomerUserName.Equals(item.CustomerUserName) && n.OrderType == item.OrderType) == null)
                {
                    item.MemberCreditDetails = usages.Where(m => m.CustomerUserName.Equals(item.CustomerUserName, StringComparison.CurrentCultureIgnoreCase)).ToList();
                    if (reminds.Any())
                    {
                        foreach (var detail in item.MemberCreditDetails)
                        {
                            detail.RepaymentReminds = reminds.Where(m => m.WithdrawalOrder.Equals(detail.CreditUsageDetailId, StringComparison.CurrentCultureIgnoreCase)).ToList();
                        }
                    }
                    var result = Mapper.Map<MemberCredit>(item);
                    if (_memberCreditRepository.Add(result))
                    {
                        dtos.Add(result);
                    }
                }
            }
            return Mapper.Map<List<MemberCreditDTO>>(dtos);
            //}
            //else
            //{
            //    var usernames = usages.Select(m => m.CustomerUserName).ToList().Distinct();
            //    var memberCredit = _memberCreditRepository.GetMemberCreditDetailListByFilter(m => usernames.Contains(m.CustomerUserName));
            //    foreach (var item in memberCredit)
            //    {
            //        item.MemberCreditDetails.ToList().AddRange(Mapper.Map<List<CreditUsageDetail>>(usages.Where(m => m.CustomerUserName == item.CustomerUserName)));
            //        if (reminds.Any())
            //        {
            //            foreach (var detail in item.MemberCreditDetails)
            //            {
            //                detail.RepaymentReminds.ToList().AddRange(Mapper.Map<List<RepaymentRemind>>(reminds.Where(m => m.WithdrawalOrder.Equals(detail.Id, StringComparison.CurrentCultureIgnoreCase))));
            //            }
            //        }
            //    }
            //    if (_memberCreditRepository.Add(memberCredit) > 0)
            //    {
            //        return Mapper.Map<List<MemberCreditDTO>>(memberCredit);
            //    }
            //    return new List<MemberCreditDTO>();
            //}
            //}
            //else
            //{
            //    var usernames = reminds.Select(m => m.CustomerUserName).ToList().Distinct();
            //    var memberCredit = _memberCreditRepository.GetMemberCreditDetailListByFilter(m => usernames.Contains(m.CustomerUserName));
            //    foreach (var item in memberCredit)
            //    {
            //        if (reminds.Any())
            //        {
            //            foreach (var detail in item.MemberCreditDetails)
            //            {
            //                detail.RepaymentReminds.ToList().AddRange(Mapper.Map<List<RepaymentRemind>>(reminds.Where(m => m.WithdrawalOrder.Equals(detail.Id, StringComparison.CurrentCultureIgnoreCase))));
            //            }
            //        }
            //    }
            //    if (_memberCreditRepository.Add(memberCredit) > 0)
            //    {
            //        return Mapper.Map<List<MemberCreditDTO>>(memberCredit);
            //    }
            //}
        }


        public MemberCreditDTO SendMemberCredit(MemberCreditDTO membercredit, MemberCreditDTO type = null)
        {
            var result = Mapper.Map<MemberCredit>(membercredit);
            if (type == null)
            {
                return _memberCreditRepository.Add(result) ? Mapper.Map<MemberCreditDTO>(result) : null;
            }
            else
            {
                var newresult = _memberCreditRepository.FindById(membercredit.ReferenceId.ObjToInt());
                newresult.ReferenceId = type.Id.ToString();
                _memberCreditRepository.Modify(newresult, new[] { "ReferenceId" }, false);
                foreach (CreditUsageDetailDTO t in type.MemberCreditDetails)
                {

                    var newcreditresult = _creditUsageDetailRepository.FindById(t.ReferenceId);
                    newcreditresult.ReferenceId = t.Id;
                    _creditUsageDetailRepository.Modify(newcreditresult, new[] { "ReferenceId" }, false);
                    foreach (RepaymentRemindDTO t1 in t.RepaymentReminds)
                    {
                        var newdetailresult = _repaymentRemindRepository.FindById(t1.ReferenceId.ObjToInt());
                        newdetailresult.ReferenceId = t1.Id.ToString();
                        _repaymentRemindRepository.Modify(newdetailresult, new[] { "ReferenceId" }, false);
                    }
                }
                return FinancingCreditContext.Commit() > 0 ? new MemberCreditDTO() : null;
            }
        }

        public bool RemoveMemberCredit(MemberCreditDTO membercredit)
        {
            var result = Mapper.Map<MemberCredit>(membercredit);
            foreach (var item in result.MemberCreditDetails)
            {
                foreach (var reminds in item.RepaymentReminds)
                {
                    _repaymentRemindRepository.Remove(reminds.Id, false);
                }
                _creditUsageDetailRepository.Remove(item.Id, false);
            }
            _memberCreditRepository.Remove(result.Id, false);
            return FinancingCreditContext.Commit() > 0;
        }
    }
}
